/**
 * 文件名: src/utils/platform.ts
 * 
 * 文件概述:
 * 平台检测和存储操作工具，统一处理网页版和桌面版的存储和交互逻辑。
 * 更新AI调用接口，支持多文件参考上下文。
 * 
 * 依赖项:
 * - idb: 用于网页版IndexedDB操作
 * - @tauri-apps/api: 用于桌面版文件系统操作、对话框和HTTP请求(AI API调用)
 * 
 * 类型定义:
 * - Platform: 'web' | 'desktop' 平台类型
 * - StorageResult<T>: { data?: T, error?: string } 统一返回结果类型
 * 
 * 导出函数:
 * - isPlatform(platform: Platform): boolean - 检测当前运行环境
 * - getChapters(): Promise<StorageResult<Chapter[]>> - 获取章节列表
 * - saveChapter(chapter: Chapter): Promise<StorageResult<void>> - 保存章节内容
 * - showFileSelector(): Promise<StorageResult<string>> - 显示文件选择器
 * 
 * // 更新AI调用接口，明确支持上下文参数
 * - callAI(
 *     prompt: string, 
 *     context?: string
 *   ): Promise<StorageResult<string>> - 调用AI接口
 * 
 * AI调用实现细节:
 * 1. 网页版实现:
 *    - 通过fetch访问/api?type=ai
 *    - 传递prompt和context参数
 *    - context参数包含选中章节和参考文件内容
 * 
 * 2. 桌面版实现:
 *    - 直接调用Tauri命令call_ai
 *    - 传递完整请求对象，包含prompt和context
 * 
 * 错误处理:
 * - 检查请求大小，过大时返回错误
 * - 超时处理(30秒超时)
 * - 网络错误处理
 * 
 * 注意事项:
 * - 确保网页版和桌面版保持一致的API接口
 * - 处理可能的大文本传输问题，考虑压缩或截断
 * - 所有异步操作返回Promise并处理错误
 * - 考虑添加请求取消功能(AbortController)
 */

import { openDB, IDBPDatabase } from 'idb';
import { Chapter } from '../store';
// 导入类型声明，无需导入实际模块
import '../types/tauri';

// 扩展Window接口以包含Tauri
declare global {
  interface Window {
    __TAURI__?: {
      invoke?: (command: string, args?: any) => Promise<any>;
    };
    NEXT_PUBLIC_APP_MODE?: string;
  }
}

// Tauri API 接口与实例
let tauriInvoke: ((command: string, args?: any) => Promise<any>) | null = null;
let tauriFsInitialized = false;
let tauriDialogInitialized = false;
let tauriHttpInitialized = false;

// 实例化后的API对象
let tauriFs: any = null;
let tauriDialog: any = null;
let tauriHttp: any = null;

// 动态导入Tauri API，避免在网页版中报错
const importTauriApis = async () => {
  try {
    // 仅在桌面版环境中导入Tauri相关模块
    if (typeof window !== 'undefined' && window.__TAURI__) {
      console.log("正在初始化Tauri API...");
      
      // 从window.__TAURI__获取invoke函数
      if (window.__TAURI__.invoke) {
        tauriInvoke = window.__TAURI__.invoke;
        console.log("成功获取Tauri invoke函数");
      } else {
        console.warn("无法从window.__TAURI__获取invoke函数");
      }
      
      try {
        // 初始化文件系统插件
        const fsPlugin = await import('@tauri-apps/plugin-fs');
        if (fsPlugin && typeof fsPlugin.init === 'function') {
          await fsPlugin.init();
          tauriFsInitialized = true;
          console.log("文件系统插件初始化成功");
          
          // 获取文件系统API
          const fs = await import('@tauri-apps/api/fs');
          tauriFs = fs;
        } else {
          console.warn("文件系统插件缺少init方法");
        }
      } catch (fsError) {
        console.warn("文件系统插件初始化失败:", fsError);
      }
      
      try {
        // 初始化对话框插件
        const dialogPlugin = await import('@tauri-apps/plugin-dialog');
        if (dialogPlugin && typeof dialogPlugin.init === 'function') {
          await dialogPlugin.init();
          tauriDialogInitialized = true;
          console.log("对话框插件初始化成功");
          
          // 获取对话框API
          const dialog = await import('@tauri-apps/api/dialog');
          tauriDialog = dialog;
        } else {
          console.warn("对话框插件缺少init方法");
        }
      } catch (dialogError) {
        console.warn("对话框插件初始化失败:", dialogError);
      }
      
      try {
        // 初始化HTTP插件
        const httpPlugin = await import('@tauri-apps/plugin-http');
        if (httpPlugin && typeof httpPlugin.init === 'function') {
          await httpPlugin.init();
          tauriHttpInitialized = true;
          console.log("HTTP插件初始化成功");
          
          // 获取HTTP API
          const http = await import('@tauri-apps/api/http');
          tauriHttp = http;
        } else {
          console.warn("HTTP插件缺少init方法");
        }
      } catch (httpError) {
        console.warn("HTTP插件初始化失败:", httpError);
      }
    }
  } catch (error) {
    console.error('Tauri API初始化过程中发生错误:', error);
  }
};

// 平台类型定义
export type Platform = 'web' | 'desktop';

// 统一返回结果类型
export type StorageResult<T> = {
  data?: T;
  error?: string;
};

// 数据库名称和版本
const DB_NAME = 'novelist-app';
const DB_VERSION = 1;
const CHAPTERS_STORE = 'chapters';

// 数据库连接
let dbPromise: Promise<IDBPDatabase> | null = null;

/**
 * 初始化存储
 * 在应用启动时调用
 */
export async function init(): Promise<StorageResult<void>> {
  try {
    await importTauriApis();
    
    if (isPlatform('web')) {
      // 初始化IndexedDB
      dbPromise = openDB(DB_NAME, DB_VERSION, {
        upgrade(db) {
          // 创建chapters存储对象
          if (!db.objectStoreNames.contains(CHAPTERS_STORE)) {
            const store = db.createObjectStore(CHAPTERS_STORE, { keyPath: 'id' });
            store.createIndex('title', 'title', { unique: false });
          }
        },
      });
      
      await dbPromise;
    } else if (isPlatform('desktop')) {
      // 确保章节目录存在
      if (!tauriInvoke || !tauriFsInitialized) {
        console.warn('Tauri API未完全初始化，尝试创建章节目录可能会失败');
      }
      
      try {
        // 使用invoke直接调用命令创建目录
        if (tauriInvoke) {
          await tauriInvoke('plugin:fs|create_dir', { 
            dir: await getChaptersDir(),
            recursive: true 
          });
          console.log('章节目录创建成功');
        }
      } catch (error) {
        // 目录可能已存在，忽略错误
        console.log('章节目录可能已存在:', error);
      }
    }
    
    return { data: undefined };
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return { error: `初始化存储失败: ${errorMessage}` };
  }
}

/**
 * 检测当前运行环境
 * @param platform 要检测的平台类型
 * @returns 是否为指定平台
 */
export function isPlatform(platform: Platform): boolean {
  const isTauri = typeof window !== 'undefined' && !!window.__TAURI__;
  
  // 也可以使用环境变量来强制指定平台类型(用于测试)
  const envPlatform = typeof process !== 'undefined' && process.env.NEXT_PUBLIC_APP_MODE
    ? process.env.NEXT_PUBLIC_APP_MODE
    : (typeof window !== 'undefined' ? window.NEXT_PUBLIC_APP_MODE : null);
  
  if (envPlatform === 'web' || envPlatform === 'desktop') {
    return envPlatform === platform;
  }
  
  return (platform === 'desktop' && isTauri) || (platform === 'web' && !isTauri);
}

/**
 * 获取章节目录路径(仅桌面版)
 * @returns 章节目录路径
 */
async function getChaptersDir(): Promise<string> {
  if (!isPlatform('desktop')) {
    return '';
  }
  
  try {
    if (tauriInvoke) {
      // 使用invoke调用获取应用数据目录
      const appDataDir = await tauriInvoke('plugin:path|app_data_dir');
      return `${appDataDir}chapters`;
    }
    return '';
  } catch (error) {
    console.error('Failed to get chapters directory:', error);
    return '';
  }
}

/**
 * 估算文本的token数量(简单实现)
 * @param text 要估算的文本
 * @returns 估算的token数量
 */
export function estimateTokens(text: string): number {
  if (!text) return 0;
  // 简单估算: 每4个字符约1个token
  return Math.ceil(text.length / 4);
}

/**
 * 获取章节列表
 * @returns 章节列表或错误信息
 */
export async function getChapters(): Promise<StorageResult<Chapter[]>> {
  try {
    if (isPlatform('web')) {
      // 从IndexedDB获取章节
      if (!dbPromise) {
        await init();
      }
      
      const db = await dbPromise;
      if (!db) {
        return { error: '数据库未初始化' };
      }
      
      const chapters = await db.getAll(CHAPTERS_STORE);
      return { data: chapters };
    } else {
      // 从文件系统获取章节
      if (!tauriInvoke || !tauriFsInitialized) {
        return { error: 'Tauri文件系统API未初始化' };
      }
      
      const chaptersDir = await getChaptersDir();
      
      try {
        // 使用invoke直接调用命令读取目录
        const files = await tauriInvoke('plugin:fs|read_dir', { 
          dir: chaptersDir,
          recursive: false
        });
        
        const chapters: Chapter[] = [];
        for (const file of files) {
          if (file.name.endsWith('.json')) {
            try {
              // 读取章节文件
              const content = await tauriInvoke('plugin:fs|read_text_file', {
                path: `${chaptersDir}/${file.name}`
              });
              
              const chapter = JSON.parse(content) as Chapter;
              chapters.push(chapter);
            } catch (error) {
              console.warn(`Failed to read chapter file ${file.name}:`, error);
            }
          }
        }
        
        return { data: chapters };
      } catch (error) {
        return { error: `无法读取章节目录: ${error}` };
      }
    }
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return { error: `获取章节失败: ${errorMessage}` };
  }
}

/**
 * 保存章节内容
 * @param chapter 要保存的章节对象
 * @returns 成功或错误信息
 */
export async function saveChapter(chapter: Chapter): Promise<StorageResult<void>> {
  try {
    if (!chapter.id) {
      return { error: '章节ID不能为空' };
    }
    
    if (isPlatform('web')) {
      // 保存到IndexedDB
      if (!dbPromise) {
        await init();
      }
      
      const db = await dbPromise;
      if (!db) {
        return { error: '数据库未初始化' };
      }
      
      await db.put(CHAPTERS_STORE, chapter);
      return { data: undefined };
    } else {
      // 保存到文件系统
      if (!tauriInvoke || !tauriFsInitialized) {
        return { error: 'Tauri文件系统API未初始化' };
      }
      
      const chaptersDir = await getChaptersDir();
      const filePath = `${chaptersDir}/${chapter.id}.json`;
      
      // 使用invoke调用写入文本文件
      await tauriInvoke('plugin:fs|write_text_file', {
        path: filePath,
        contents: JSON.stringify(chapter, null, 2)
      });
      
      return { data: undefined };
    }
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return { error: `保存章节失败: ${errorMessage}` };
  }
}

/**
 * 显示文件选择器
 * @returns 选中的文件路径或错误信息
 */
export async function showFileSelector(): Promise<StorageResult<string>> {
  try {
    if (isPlatform('web')) {
      // 网页版使用HTML文件选择器
      return new Promise((resolve) => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.txt,.md,.json';
        
        input.onchange = () => {
          const file = input.files?.[0];
          if (file) {
            resolve({ data: file.name });
          } else {
            resolve({ data: '' });
          }
          // 清理DOM
          input.remove();
        };
        
        // 模拟点击触发文件选择
        input.click();
      });
    } else {
      // 桌面版使用Tauri对话框
      if (!tauriInvoke || !tauriDialogInitialized) {
        return { error: 'Tauri对话框API未初始化' };
      }
      
      try {
        // 使用invoke调用打开文件对话框
        const filePath = await tauriInvoke('plugin:dialog|open', {
          multiple: false,
          filters: [{
            name: 'Text',
            extensions: ['txt', 'md', 'json']
          }]
        });
        
        if (filePath) {
          return { data: filePath as string };
        } else {
          return { data: '' }; // 用户取消选择
        }
      } catch (error) {
        return { error: `打开文件对话框失败: ${error}` };
      }
    }
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return { error: `文件选择失败: ${errorMessage}` };
  }
}

/**
 * 调用AI接口
 * @param prompt 用户提示
 * @param context 上下文内容(包括当前章节和参考文件)
 * @returns AI响应或错误信息
 */
export async function callAI(
  prompt: string,
  context?: string
): Promise<StorageResult<string>> {
  try {
    // 检查提示是否为空
    if (!prompt.trim()) {
      return { error: '提示不能为空' };
    }
    
    // 估算token数量
    const totalTokens = estimateTokens(prompt) + estimateTokens(context || '');
    if (totalTokens > 4000) {
      return { error: '提示和上下文内容过长，请减少文本或分割请求' };
    }
    
    // 根据平台调用不同的AI接口
    if (isPlatform('web')) {
      // 网页版: 通过API路由调用
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 30000); // 30秒超时
      
      try {
        const response = await fetch('/api?type=ai', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ prompt, context }),
          signal: controller.signal
        });
        
        clearTimeout(timeoutId);
        
        if (!response.ok) {
          const errorData = await response.json();
          return { error: errorData.error || `请求失败: ${response.status}` };
        }
        
        const data = await response.json();
        return data as StorageResult<string>;
      } catch (fetchError: unknown) {
        clearTimeout(timeoutId);
        
        if (fetchError instanceof Error && fetchError.name === 'AbortError') {
          return { error: '请求超时，请稍后重试' };
        }
        
        const errorMessage = fetchError instanceof Error ? fetchError.message : String(fetchError);
        return { error: `请求失败: ${errorMessage}` };
      }
    } else {
      // 桌面版: 直接调用Tauri命令
      if (!tauriInvoke) {
        return { error: 'Tauri API未初始化' };
      }
      
      try {
        // 使用Tauri 2.x的invoke方法调用后端命令，添加明确的权限
        const response = await tauriInvoke('call_ai', {
          request: { prompt, context },
          permissions: { "http:allow-fetch": true } // 显式声明权限
        });
        
        return response as StorageResult<string>;
      } catch (error) {
        return { error: `AI调用命令失败: ${error}` };
      }
    }
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return { error: `AI调用失败: ${errorMessage}` };
  }
}

// 导出默认初始化
export default {
  init,
  isPlatform,
  getChapters,
  saveChapter,
  showFileSelector,
  callAI,
  estimateTokens
};